{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### 1 捕获异常"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 1.1 简单的捕获异常语法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# • 在程序开发中，如果 对某些代码的执行不能确定是否正确，可以增加 try(尝试) 来 捕获异常\n",
    "# • 捕获异常最简单的语法格式：\n",
    "# try:\n",
    "# 尝试执行的代码\n",
    "# except:\n",
    "# 出现错误的处理\n",
    "# • try 尝试，下方编写要尝试代码，不确定是否能够正常执行的代码\n",
    "# • except 如果不是，下方编写尝试失败的代码"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入正确的数字\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    # 提示用户输入一个数字\n",
    "    num = int(input(\"请输入数字：\"))\n",
    "except:\n",
    "    print(\"请输入正确的数字\")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 1.2 错误类型捕获"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "try:\n",
    "# 尝试执行的代码\n",
    "   pass\n",
    "except 错误类型 1:\n",
    "# 针对错误类型 1，对应的代码处理\n",
    "  pass\n",
    "except (错误类型 2, 错误类型 3):\n",
    "# 针对错误类型 2 和 3，对应的代码处理\n",
    "  pass\n",
    "except Exception as result:\n",
    "  print(\"未知错误 %s\" % result)\n",
    "# • 当 Python 解释器 抛出异常 时，最后一行错误信息的第一个单词，就是错误类型"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "ename": "ZeroDivisionError",
     "evalue": "division by zero",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mZeroDivisionError\u001B[0m                         Traceback (most recent call last)",
      "Input \u001B[1;32mIn [5]\u001B[0m, in \u001B[0;36m<cell line: 1>\u001B[1;34m()\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m      2\u001B[0m     num \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mint\u001B[39m(\u001B[38;5;28minput\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m请输入整数：\u001B[39m\u001B[38;5;124m\"\u001B[39m))\n\u001B[1;32m----> 3\u001B[0m     result \u001B[38;5;241m=\u001B[39m \u001B[38;5;241;43m8\u001B[39;49m\u001B[43m \u001B[49m\u001B[38;5;241;43m/\u001B[39;49m\u001B[43m \u001B[49m\u001B[43mnum\u001B[49m\n\u001B[0;32m      4\u001B[0m     \u001B[38;5;28mprint\u001B[39m(result)\n\u001B[0;32m      5\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m:\n",
      "\u001B[1;31mZeroDivisionError\u001B[0m: division by zero"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    num = int(input(\"请输入整数：\"))\n",
    "    result = 8 / num\n",
    "    print(result)\n",
    "except ValueError:\n",
    "    print(\"请输入正确的整数\")\n",
    "except ZeroDivisionError:\n",
    "    print(\"除0错误\")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 捕获未知错误\n",
    "\n",
    "# • 在开发时，要预判到所有可能出现的错误，还是有一定难度的\n",
    "# • 如果希望程序 无论出现任何错误，都不会因为 Python 解释器 抛出异常而被终\n",
    "# 止，可以再增加一个 except(记日志)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "invalid literal for int() with base 10: 'xi'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    num = int(input(\"请输入整数：\"))\n",
    "    result = 8 / num\n",
    "    print(result)\n",
    "except Exception as result:\n",
    "    print(result)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 1,3 异常捕获完整语法"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "try:\n",
    "# 尝试执行的代码\n",
    "    pass\n",
    "except 错误类型 1:\n",
    "# 针对错误类型 1，对应的代码处理\n",
    "    pass\n",
    "except 错误类型 2:\n",
    "# 针对错误类型 2，对应的代码处理\n",
    "    pass\n",
    "except (错误类型 3, 错误类型 4):\n",
    "# 针对错误类型 3 和 4，对应的代码处理\n",
    "    pass\n",
    "except Exception as result:\n",
    "# 打印错误信息\n",
    "    print(result)\n",
    "else:\n",
    "# 没有异常才会执行的代码\n",
    "    pass\n",
    "finally:\n",
    "# 无论是否有异常，都会执行的代码\n",
    "    print(\"无论是否有异常，都会执行的代码\")\n",
    "\n",
    "# • else 只有在没有异常时才会执行的代码\n",
    "# • finally 无论是否有异常，都会执行的代码"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "未知错误 division by zero\n",
      "执行完成，但是不保证正确\n"
     ]
    },
    {
     "ename": "KeyError",
     "evalue": "'__file__'",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mZeroDivisionError\u001B[0m                         Traceback (most recent call last)",
      "Input \u001B[1;32mIn [9]\u001B[0m, in \u001B[0;36m<cell line: 1>\u001B[1;34m()\u001B[0m\n\u001B[0;32m      2\u001B[0m num \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mint\u001B[39m(\u001B[38;5;28minput\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m请输入整数：\u001B[39m\u001B[38;5;124m\"\u001B[39m))\n\u001B[1;32m----> 3\u001B[0m result \u001B[38;5;241m=\u001B[39m \u001B[38;5;241;43m8\u001B[39;49m\u001B[43m \u001B[49m\u001B[38;5;241;43m/\u001B[39;49m\u001B[43m \u001B[49m\u001B[43mnum\u001B[49m\n\u001B[0;32m      4\u001B[0m \u001B[38;5;28mprint\u001B[39m(result)\n",
      "\u001B[1;31mZeroDivisionError\u001B[0m: division by zero",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001B[1;31mKeyError\u001B[0m                                  Traceback (most recent call last)",
      "Input \u001B[1;32mIn [9]\u001B[0m, in \u001B[0;36m<cell line: 1>\u001B[1;34m()\u001B[0m\n\u001B[0;32m      7\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m result:\n\u001B[0;32m      8\u001B[0m     \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m未知错误 \u001B[39m\u001B[38;5;132;01m%s\u001B[39;00m\u001B[38;5;124m\"\u001B[39m \u001B[38;5;241m%\u001B[39m result)\n\u001B[1;32m----> 9\u001B[0m     \u001B[38;5;28mprint\u001B[39m(\u001B[43mresult\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m__traceback__\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mtb_frame\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mf_globals\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43m__file__\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m]\u001B[49m) \u001B[38;5;66;03m# 发生异常所在的文件\u001B[39;00m\n\u001B[0;32m     10\u001B[0m     \u001B[38;5;28mprint\u001B[39m(result\u001B[38;5;241m.\u001B[39m__traceback__\u001B[38;5;241m.\u001B[39mtb_lineno) \u001B[38;5;66;03m# 发生异常所在的行数\u001B[39;00m\n\u001B[0;32m     11\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n",
      "\u001B[1;31mKeyError\u001B[0m: '__file__'"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    num = int(input(\"请输入整数：\"))\n",
    "    result = 8 / num\n",
    "    print(result)\n",
    "except ValueError:\n",
    "    print(\"请输入正确的整数\")\n",
    "except Exception as result:\n",
    "    print(\"未知错误 %s\" % result)\n",
    "else:\n",
    "    print(\"正常执行\")\n",
    "finally:\n",
    "    print(\"执行完成，但是不保证正确\")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 2 异常传递"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# • 异常的传递 —— 当 函数/方法 执行 出现异常，会 将异常传递 给 函数/方法的 调用一方\n",
    "# • 如果 传递到主程序，仍然 没有异常处理，程序才会被终止\n",
    "# 提示\n",
    "# • 在开发中，可以在主函数中增加 异常捕获\n",
    "# • 而在主函数中调用的其他函数，只要出现异常，都会传递到主函数的 异常捕获 中\n",
    "# • 这样就不需要在代码中，增加大量的 异常捕获，能够保证代码的整洁"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "未知错误invalid literal for int() with base 10: ''\n"
     ]
    }
   ],
   "source": [
    "# 需求\n",
    "# 1 定义函数 demo1() 提示用户输入一个整数并且返回\n",
    "# 2 定义函数 demo2() 调用 demo1()\n",
    "# 3 在主程序中调用 demo2()\n",
    "\n",
    "def demo1():\n",
    "    a = int(input(\"请输入一个整数：\"))\n",
    "    return a\n",
    "\n",
    "def demo2():\n",
    "    demo1()\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    try:\n",
    "        demo2()\n",
    "    except Exception as result:\n",
    "        print(\"未知错误%s\" % result)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 3 抛出raise异常"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# • Python 中提供了一个 Exception 异常类\n",
    "# • 在开发时，如果满足 特定业务需求时，希望 抛出异常，可以：\n",
    "#    l) 创建 一个 Exception 的 对象\n",
    "#    m)使用 raise 关键字 抛出 异常对象"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 需求\n",
    "# • 定义 input_password 函数，提示用户输入密码\n",
    "# • 如果用户输入长度 < 8，抛出异常\n",
    "# • 如果用户输入长度 >=8，返回输入的密码"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123456789\n"
     ]
    }
   ],
   "source": [
    "def input_password():\n",
    "\n",
    "    a = input(\"输入密码\")\n",
    "\n",
    "    if len(a) < 8:\n",
    "        print(\"主动抛出异常\")\n",
    "        # 1> 创建异常对象 - 可以使用错误信息字符串作为参数\n",
    "        ex = Exception(\"密码长度不够\")\n",
    "\n",
    "        raise ex\n",
    "    return a\n",
    "try:\n",
    "    print(input_password())\n",
    "except Exception as result:\n",
    "    print(result)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}